package org.ky.generator.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.raddle.jdbc.meta.table.ColumnInfo;

/**
 * 属性帮助类
 * 
 * @author K.y
 *
 */
public class AttributeHelper {
	/**
	 * 根据列名获取属性名称
	 * 
	 * @param columnName
	 * @return
	 */
	public static String getPropertyName(String columnName) {
		columnName = dbToJava(columnName);
		char[] chars = columnName.toCharArray();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < chars.length; i++) {
			char c = chars[i];
			if (c == '_' && i < chars.length - 1) {
				sb.append(Character.toUpperCase(chars[i + 1]));
				i++;//
			} else if (c != '_') {
				sb.append(Character.toLowerCase(c));
			}
		}
		return sb.toString();
	}

	/**
	 * 根据表字段获取方法名后缀
	 * 
	 * @param columnName
	 * @return
	 */
	public static String getMethodNameSuffixFromColumnName(String columnName) {
		return getMethodNameSuffix(getPropertyName(columnName));
	}

	/**
	 * 根据属性名获取方法名后缀
	 * 
	 * @param propName
	 * @return
	 */
	public static String getMethodNameSuffix(String propName) {
		if (Character.isUpperCase(propName.charAt(0))) {
			if (propName.length() == 1 || Character.isLowerCase(propName.charAt(1))) {
				throw new IllegalArgumentException("非法属性名[" + propName + "]");
			}
			return propName;
		} else {
			if (propName.length() > 1 && Character.isUpperCase(propName.charAt(1))) {
				return propName;
			} else {
				return StringUtils.capitalize(propName);
			}
		}
	}

	/**
	 * 根据表名获取表属性名称
	 * 
	 * @param tableName
	 * @return
	 */
	public static String getJavaPropertyName(String tableName) {
		tableName = tableName.substring(tableName.indexOf('_') + 1);
		tableName = tableName.substring(tableName.indexOf('_') + 1);
		return getPropertyName(tableName);
	}

	/**
	 * 根据表名获取类名称
	 * 
	 * @param tableName
	 * @return
	 */
	public static String getClassName(String tableName) {
		// 最笨的切两个'_'的办法 ^_^
		tableName = tableName.substring(tableName.indexOf('_') + 1);
		// tableName = tableName.substring(tableName.indexOf('_') + 1);
		return myClassNameFilter(StringUtils.capitalize(getPropertyName(tableName)));
	}

	// public static String getClassName(String tableName, String prefix, String
	// suffix) {
	// return StringUtils.defaultString(prefix) +
	// myClassNameFilter(StringUtils.capitalize(getPropertyName(tableName)))
	// + StringUtils.defaultString(suffix) ;
	// }
	protected static String myClassNameFilter(String name) {
		// if (name.equals("Orders")) {
		// return "Order";
		// }
		return name;
	}
	
	public static String getTableName(String className) {
		return className;
	}

	/**
	 * 是否存在字段
	 * 
	 * @param props
	 * @param columnName
	 * @return
	 */
	public static boolean hasField(List<Map<Object, Object>> props, String columnName) {
		for (Map<Object, Object> prop : props) {
			if (columnName.equals(prop.get("name"))) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 类型是否是字符串
	 * 
	 * @param columnType
	 * @return
	 */
	public static boolean isTypeIsString(String columnType) {
		return PropertyHelper.in(columnType, "CHAR", "VARCHAR", "TEXT", "MEDIUMTEXT");
	}

	/**
	 * 类型是否是日期
	 * 
	 * @param columnType
	 * @return
	 */
	public static boolean isTypeIsDate(String columnType) {
		return PropertyHelper.in(columnType, "DATETIME", "DATE");
	}

	/**
	 * 类型是否是整数型
	 * 
	 * @param columnType
	 * @return
	 */
	public static boolean isTypeIsInteger(String columnType) {
		return PropertyHelper.in(columnType, "INT", "SMALLINT", "TINYINT", "BIGINT", "BIGINT UNSIGNED", "INT UNSIGNED");
	}

	/**
	 * 类型是否是数字
	 * 
	 * @param columnType
	 * @return
	 */
	public static boolean isTypeIsNumber(String columnType) {
		return PropertyHelper.in(columnType, "INT", "SMALLINT", "TINYINT", "BIGINT", "DECIMAL", "DOUBLE",
				"BIGINT UNSIGNED", "INT UNSIGNED");
	}

	/**
	 * 根据数据库列类型获取Java数据类型
	 * 
	 * @param colunmInfo
	 * @return
	 */
	public static String getJavaType(ColumnInfo colunmInfo) {
		String columnName = colunmInfo.getColumnTypeName();
		if (PropertyHelper.in(columnName, "CHAR", "VARCHAR", "TEXT", "MEDIUMTEXT")) {
			return "java.lang.String";
		}
		if (PropertyHelper.in(columnName, "INT", "SMALLINT", "TINYINT", "INT UNSIGNED")) {
			return "java.lang.Integer";
		}
		if (PropertyHelper.in(columnName, "DATETIME", "DATE", "TIMESTAMP")) {
			return "java.util.Date";
		}
		if (PropertyHelper.in(columnName, "BIGINT", "BIGINT UNSIGNED")) {
			return "java.lang.Long";
		}
		if (PropertyHelper.in(columnName, "DOUBLE")) {
			return "java.lang.Double";
		}
		if (PropertyHelper.in(columnName, "DECIMAL")) {
			return "java.math.BigDecimal";
		}
		if (PropertyHelper.in(columnName, "BIT")) {
			return "java.lang.Boolean";
		}
		return "Unknown[" + columnName + "]";
	}

	/**
	 * 根据数据库列类型（Mysql）获取Java类型
	 * 
	 * @param colunmInfo
	 * @return
	 */
	public static String getJavaType_Mysql(ColumnInfo colunmInfo) {
		String columnName = colunmInfo.getColumnTypeName();
		if (PropertyHelper.in(columnName, "CHAR", "VARCHAR", "TEXT", "MEDIUMTEXT")) {
			return "String";
		}
		if (PropertyHelper.in(columnName, "BIGINT")) {
			return "Long";
		}
		if (PropertyHelper.in(columnName, "INT")) {
			return "Integer";
		}
		if (PropertyHelper.in(columnName, "DATETIME", "DATE")) {
			return "java.util.Date";
		}
		if (PropertyHelper.in(columnName, "SMALLINT", "TINYINT")) {
			return "Integer";
		}
		if (PropertyHelper.in(columnName, "DECIMAL")) {
			return "java.math.BigDecimal";
		}
		return "Unknown[" + columnName + "]";
	}

	/**
	 * 根据数据库类型（Oracle）获取Java数据类型
	 * 
	 * @param colunmInfo
	 * @return
	 */
	public static String getJavaType_ORACLE(ColumnInfo colunmInfo) {
		if ("CHAR".equals(colunmInfo.getColumnTypeName()) || "VARCHAR".equals(colunmInfo.getColumnTypeName())
				|| "VARCHAR2".equals(colunmInfo.getColumnTypeName())) {
			return "String";
		} else if ("DECIMAL".equals(colunmInfo.getColumnTypeName()) || "NUMBER".equals(colunmInfo.getColumnTypeName())
				|| "INT".equals(colunmInfo.getColumnTypeName())) {
			if (colunmInfo.getScale() > 0) {
				return "java.math.BigDecimal";
			} else if (colunmInfo.getLength() < 10) {
				return "Integer";
			} else {
				return "Long";
			}
		} else if ("DATE".equals(colunmInfo.getColumnTypeName())) {
			return "java.util.Date";
		} else {
			return "Unknown[" + colunmInfo.getColumnTypeName() + "]";
		}
	}

	/**
	 * 
	 * @param name
	 * @return
	 */
	public static String dbToJava(String name) {
		String[] orgn = name.split("_");
		String[] res = new String[orgn.length];
		for (int i = 0; i < orgn.length; i++) {
			res[i] = dbToJavaRuleFunc(orgn[i]);
		}
		return StringUtils.join(res, "_");
	}

	/**
	 * 
	 * @param n
	 * @return
	 */
	private static String dbToJavaRuleFunc(String n) {
		String v = dbToJavaRule.get(n);
		return v != null ? v : n;
	}

	/** 数据库转换Java规则 */
	static Map<String, String> dbToJavaRule = new HashMap<String, String>();
	/**
	 * 初始化规则对应表
	 */
	static {
		dbToJavaRule.put("ord", "order");
		dbToJavaRule.put("usr", "user");
		dbToJavaRule.put("aud", "audit");
		dbToJavaRule.put("conf", "configure");
		dbToJavaRule.put("stat", "status");
		dbToJavaRule.put("info", "info");
		dbToJavaRule.put("org", "org");
		dbToJavaRule.put("addr", "address");
		dbToJavaRule.put("msg", "msg");
		dbToJavaRule.put("his", "history");
		dbToJavaRule.put("da", "daily");
		dbToJavaRule.put("pic", "pic");
		dbToJavaRule.put("bat", "bat");
		dbToJavaRule.put("err", "err");
		dbToJavaRule.put("bak", "bak");
		dbToJavaRule.put("del", "delete");
		dbToJavaRule.put("upd", "update");
		dbToJavaRule.put("int", "insert");
		dbToJavaRule.put("mdfy", "modify");
		dbToJavaRule.put("cred", "creditcard");
		dbToJavaRule.put("mem", "member");
		dbToJavaRule.put("pwd", "pwd");
		dbToJavaRule.put("agt", "agent");
		//
		dbToJavaRule.put("desc", "desc");
		dbToJavaRule.put("cd", "code");
		dbToJavaRule.put("typ", "type");
	}
}
